﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Asptcp.Core
{
    public class AsptcpServer
    {
        private TcpListener _listener;
        private AsptcpOption _option;
        TaskFactory taskFactory = new TaskFactory();
        List<Task> tasks = new List<Task>();
        List<TcpClient> tcpClients = new List<TcpClient>();
        byte[] reOk = UTF8Encoding.UTF8.GetBytes("ok");
        //int maxLength = 1024;
        public AsptcpServer(IPAddress localaddr, int port, AsptcpOption option = null)
        {
            if (option == null)
                option = new AsptcpOption();
            _option = option;
            _listener = new TcpListener(localaddr, port);
        }
        public void Start()
        {
            //Console.WriteLine("开始监听");
            _listener.Start();
            while (true)
            {
                if (_listener.Pending())
                {
                    _listener.BeginAcceptTcpClient(new AsyncCallback(onAcceptTcpClientCallback), _listener);
                }
                Thread.Sleep(10);
            }
        }
        byte[] bts = new byte[1024];
        private void onAcceptTcpClientCallback(IAsyncResult ar)
        {
            TcpListener listener = (TcpListener)ar.AsyncState;
            TcpClient client = listener.EndAcceptTcpClient(ar);
            Console.WriteLine("BeginAcceptTcpClient已结束");
            tcpClients.Add(client);
            Console.WriteLine("tcpClients.Count:" + tcpClients.Count);
            NetworkStream networkStream = client.GetStream();

            if (networkStream.CanRead)
            {
                networkStream.BeginRead(bts, 0, bts.Length, new AsyncCallback(ReadStreamCallback), networkStream);
            }
            else
            {
                Console.WriteLine("Sorry.  You cannot read to this NetworkStream.");
            }
            // Check to see if this NetworkStream is writable.
            if (networkStream.CanWrite)
            {

                byte[] myWriteBuffer = Encoding.UTF8.GetBytes("Are you receiving this message?");
                networkStream.BeginWrite(myWriteBuffer, 0, myWriteBuffer.Length,
                                                             new AsyncCallback(WriteStreamCallback),
                                                             networkStream);
                //allDone.WaitOne();
            }
            else
            {
                Console.WriteLine("Sorry.  You cannot write to this NetworkStream.");
            }
            
        }
        private void ReadStreamCallback(IAsyncResult ar)
        {
            NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState;
            //byte[] myReadBuffer = new byte[_option.timeBuffLength];
            //String myCompleteMessage = "";
            int numberOfBytesRead;
            numberOfBytesRead = myNetworkStream.EndRead(ar);
            string myCompleteMessage = Encoding.UTF8.GetString(bts, 0, numberOfBytesRead);
            Console.WriteLine("服务端收到消息：" + myCompleteMessage);
            // message received may be larger than buffer size so loop through until you have it all.
            while (true)
            {
                if (myNetworkStream.DataAvailable)
                {
                    myNetworkStream.BeginRead(bts, 0, bts.Length,
                                                           new AsyncCallback(ReadStreamCallback),
                                                           myNetworkStream);
                }
                Thread.Sleep(10);
            }

            // Print out the received message to the console.
            //Console.WriteLine("You received the following message : " + myCompleteMessage);
        }
        private void WriteStreamCallback(IAsyncResult ar)
        {
            NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState;
            myNetworkStream.EndWrite(ar);
        }
        public void Start(int backlog)
        {
            _listener.Start(backlog);

        }

        public async Task AcceptClientAsync()
        {

        }
        public async Task AcceptAsync()
        {

            while (true)
            {
                //Console.WriteLine("Pending:" + _listener.Pending());
                if (_listener.Pending())
                {
                    Console.WriteLine("有新的客户端进来");

                    Task<Task> task = taskFactory.StartNew(async () =>
                    {
                        TcpClient client = await _listener.AcceptTcpClientAsync();
                        using (var stream = client.GetStream())
                        {
                            byte[] bts = new byte[_option.timeBuffLength];
                            while (client.Connected)
                            {
                                if (stream.DataAvailable)
                                {

                                    //返回值：表示异步读取操作的任务。TResult参数的值包含读入缓冲区的总字节数。如果当前可用的字节数小于请求的字节数，则结果值可以小于请求的字节数；如果已到达流的末尾，则结果值可以为0（零）。
                                    int realLen = await stream.ReadAsync(bts, 0, bts.Length);
                                    //stream.BeginRead(bts, 0, bts.Length, ReadCallBack, stream);
                                    if (realLen <= _option.timeBuffLength)
                                    {
                                        //已读完
                                        string r = System.Text.UTF8Encoding.UTF8.GetString(bts);
                                        Console.WriteLine("服务器接收结果：" + r);
                                        Console.WriteLine("当前TaskList数量：" + tasks.Count);
                                    }
                                    else
                                    {
                                        //未读完
                                        Console.WriteLine("流未读完");
                                    }

                                }
                                if (stream.CanWrite)
                                {
                                    await stream.WriteAsync(reOk, 0, reOk.Length);
                                }
                                await Task.Delay(10);
                            }
                            Console.WriteLine("客户端连接已断开");
                        }
                    });
                    tasks.Add(await task);
                }
                await Task.Delay(10);
            }
        }
        private void ReadCallBack(IAsyncResult ar)
        {

        }


    }
}
